#ifndef GAMEENGINE_GEOMETRY_LINE3D_H
#define GAMEENGINE_GEOMETRY_LINE3D_H

#include <GameEngine/Geometry/geometry_settings.h>

#include <GameEngine/Geometry/intersection_defs.h>
#include <GameEngine/Geometry/Location/point3d.h>
#include <GameEngine/Geometry/Location/vector3d.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

namespace Line3D {
	//! Point index along a line
	enum Index {
		//! First point
		First = 0,
		//! Second point
		Second = 1
	};
}


//! Class used to represent 3D lines
/*!
 @note A line is is an oriented one-dimensional item,
	   embedded in a three-dimensional Cartesian space.
	   A line is practically made of two points of type
	   T, which allows client code to choose the level
	   of precision (typically, T will be either float
	   or double)
 @note Most algorithms expect floating point operations.
       Type T should therefore not be an integer type
 */
template <class T>
class Line3d {

public:
	Line3d();
	Line3d(const Point3d<T>& p1, const Point3d<T>& p2);
	Line3d(const Line3d& rhs);
	virtual ~Line3d();
	Line3d& operator=(const Line3d& rhs);

	Point3d<T>& p1();
	const Point3d<T>& p1() const;
	Point3d<T>& p2();
	const Point3d<T>& p2() const;

	Point3d<T>& operator[](Line3D::Index index);
	const Point3d<T>& operator[](Line3D::Index index) const;

	Point3d<T> point(const T& coordinate) const;
	IntersectionType::Type intersection(const Line3d& rhs, T& coordinate1, T* coordinate2 = nil, const T& tolerance = 0.000001) const;

	T closest_point(const Point3d<T>& rhs) const;
	T closest_point(const Line3d& rhs, IntersectionType::Type* type = nil) const;

	bool degenerate() const;

protected:
	//! Point coordinates
	Point3d<T> points_[2];
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/Geometry/Lines/line3d.hpp>

#endif
